<template>
  <div class="buy-car">
    <!-- 标题切换功能 -->
    <!-- <div class="title-wrapper">
      <template v-for="(item, index) in titleArr">
        <span @click="handleTitleClick(index)" :key="index" class="title-item">{{ item.text }}</span>
      </template>
    </div> -->
    <TitleWrapper :titleArr="titleArr" @titleClick="handleTitleClick"></TitleWrapper>

    <!-- 弹出框 -->
    <!-- <van-popup v-model="showPopup" position="top" :style="{ height: '50%' }">
      <div class="popup-wrapper">
        <template v-if="titleNumber === 0">
          <template v-for="(item, i) in titleArr[titleNumber].children">
            <span
              :class="smartIndex === i ? 'active' : ''"
              @click="handleSmartClick(item, i)"
              class="smart-item"
              :key="item.id"
            >
              {{ item.title }}
            </span>
          </template>
        </template>
        <template v-if="titleNumber === 1">品牌</template>
        <template v-if="titleNumber === 2">价格</template>
        <template v-if="titleNumber === 3">
          <h2>车龄</h2>
          <van-slider v-model="carStatus.carAge" :step="2" />

          <h2>里程</h2>
          <van-slider v-model="carStatus.mileage" :step="3" />
          <van-button @click="handleCartStatusClick">查看全部车辆</van-button>
        </template>
        <template v-if="titleNumber === 4">筛选</template>
      </div>
    </van-popup> -->

    <!-- 弹出框封装组件 -->
    <MyPopup
      :showPopup="showPopup"
      :titleNumber="titleNumber"
      :titleArr="titleArr"
      :smartIndex="smartIndex"
      :carStatus="carStatus"
      @smartClick="handleSmartClick"
      @statusClick="handleCartStatusClick"
    ></MyPopup>

    <!-- 列表组件 -->
    <div class="car-list-content">
      <CartListItem :list="list"></CartListItem>
    </div>

    <!--  监听loading,loading是一个实际存在的盒子，而list列表数据，是一个经过接口请求过来的数据，也就是
    异步数据，就会导致loading刚出来就在页面被监听到出现，这样子就会请求一次数据
      -->

    <!-- loading提示框 -->
    <template v-if="tip">
      <div class="loading" ref="loading">{{ tip }}</div>
    </template>
  </div>
</template>
<script>
import CartListItem from '@/components/CarListItem.vue'
import MyPopup from '@/components/myPopup.vue'
// 模拟接口慢的情况
import { debounce } from 'lodash'
/**
 * 效果
 * 1. 上拉加载效果（interSectionOberver）监听到dom元素是否进入可视区域
 * 2. 数据筛选（排序/过滤）
 *
 * 性能优化：
 * 1. 防抖（上拉函数加载）
 * 2. 处理监听io
 * 3. 处理数据更新后，立马获取dom的一个问题 this.$nextTick()
 */
import { mapState } from 'vuex'
import TitleWrapper from '@/components/TitleWrapper.vue'
export default {
  components: { CartListItem, MyPopup, TitleWrapper },
  data() {
    return {
      // 引用类型是按引用传递值的，改变其中的一个属性，不会让引用类型改变
      carStatus: {
        carAge: 0,
        mileage: 0,
      },
      opt: {
        page: 0,
        size: 10,
      },
      tip: '',
      list: [],
      io: null,
      // 1. 防抖第一步：定义
      handleFetchData: null,
      showPopup: false, // 是否出现弹出框
      titleNumber: 0,
      smartIndex: 0,
      copyList: [],
    }
  },
  // 监听异步数据，v-model的值
  // watch中如何打印对象数据
  watch: {
    'carStatus.carAge'(newVal, oldVal) {
      // console.log('newVal:', newVal)
    },
    'carStatus.mileage'(newVal, oldVal) {
      // console.log('newVal:', newVal)
    },
  },
  computed: {
    ...mapState(['collectArr', 'titleArr']),
  },
  created() {
    // 初始化请求数据
    this.getData()
  },
  // mounted 挂载生命周期，每次组件更新，只会执行一次
  mounted() {
    this.createObserver()
  },
  methods: {
    /**
     * @name 异步测试函数
     */
    sleep(time = 500) {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve(true)
        }, time)
      })
    },
    /**
     * @name 创建监听方法。在mounted中调用
     */
    createObserver() {
      // （防抖第三部：包装防抖函数）
      this.handleFetchData = debounce(this.getData, 1000)
      // loading 元素，监听这个loading元素，如果这个loading元素看到了，就说明滚动到了最下方。然后就请求分页数据，
      this.io = new IntersectionObserver((entries) => {
        if (entries[0].isIntersecting) {
          // 性能优化：防抖debounce，防止用户频繁上拉多次重复请求数据
          // (1. 定义函数占位名字，2. 定义请求函数 3. 利用防抖包装请求函数)
          if (this.handleFetchData) {
            this.handleFetchData()
          }
        }
      })
    },
    /**
     * @name 请求数据
     */
    async getData() {
      // 分页加加
      this.opt.page++
      // 判断是否数据加载完毕
      if (this.opt.page >= 11) {
        this.tip = '我已经到底部了'
        // 如果加载完毕：到了底部了， 停止观察 （性能优化）
        this.io.unobserve(this.$refs.loading)
        return
      }
      // 请求数据
      const data = await this.$http.get('/api/car', { params: this.opt })
      // toast提示
      this.$toast(`共为你找到${data.data.total}辆车`)
      // 数据拼接
      this.list = [...this.list, ...data.data.list]
      // 将已经本地存储之后的数据，与请求过来的数据匹配，如果收藏过了，改变状态

      this.collectArr.forEach((item) => {
        this.list.forEach((v) => {
          if (item.id === v.id) {
            v.collectFlag = item.collectFlag
          }
        })
      })
      // 等待数据加载完毕出现（控制tip内容，就是控制loading显示的时机）
      this.tip = '加载中...'
      // 修改数据之后 / 再渲染loading / 监听loading这个dom （nextTick处理dom获取问题，前提是这个dom是基于数据渲染出来的，）
      // 处理时机：就是在数据渲染完毕之后，立马获取dom
      this.$nextTick(() => {
        if (this.$refs.loading) {
          // 监听dom-获取dom-但是这个dom是数据渲染的，所以需要借助 nextTick
          this.io.observe(this.$refs.loading)
        }
      })
      //  异步任务中的微任务
      // this.$nextTick().then((res) => {})
    },
    /**
     * @name 查看车辆状态 里程 / 车龄
     */
    handleCartStatusClick() {
      this.list = this.list.filter((v) => v.carAge <= this.carStatus.carAge && v.mileage <= this.carStatus.mileage)
      this.showPopup = false
      this.tip = ''
    },
    /**
     * @name 数据筛选函数
     * type: 排序的字段
     * sort：正序还是倒序1/0  （1:正，0:倒）
     */
    handleList(type, sort) {
      console.log(type, 'type')
      // 数据过滤之前，重新请求一次数据。
      this.getData()
      if (sort === 0) {
        // 价格从高到低倒序排列
        this.list.sort((a, b) => (a[type] > b[type] ? -1 : 1))
      } else {
        // 正序排序
        this.list.sort((a, b) => (a[type] > b[type] ? 1 : -1))
      }
    },
    /**
     * @name 智能排序函数
     */
    handleSmartClick({ item, i }) {
      console.log('item:', item, i)
      this.smartIndex = i
      // 筛选数据之后，关闭弹出框
      this.showPopup = false
      if (i === 2) {
        this.handleList(item.name, 1)
      } else if (i === 3) {
        this.handleList(item.name, 0)
      } else {
        this.handleList(item.name)
      }
    },
    /**
     * @name 买车页面的标题数据切换功能
     */
    handleTitleClick(index) {
      // 知道打开的是哪一个弹出框
      this.titleNumber = index
      // 控制显示隐藏
      this.showPopup = true
    },
  },
  /**
   * keep-alive 触发的销毁生命周期
   */
  deactivated() {
    // console.log('destroyed:----------destroyed')
    // // 关闭观察器
    // this.io.disconnect()
  },
  // 销毁生命周期
  destroyed() {
    console.log('destroyed:----------destroyed')
    // 关闭观察器
    this.io.disconnect()
  },
}
</script>
<style lang="scss">
.buy-car {
  height: 100%;
  // padding: 10px;
  position: relative;
}
.popup-wrapper {
  padding: 10px;
  background: #eee;
  .smart-item {
    display: block;
    height: 45px;
    line-height: 45px;

    color: #000000;
    &.active {
      color: #00a16c;
    }
  }
}

.loading {
  height: 0.8rem;
  text-align: center;
  line-height: 0.8rem;
  font-size: 30px;
  background: lightcoral;
  color: #fff;
}
</style>
